

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.util.*;


public class TablePanel extends JPanel {
	
	private static final int STATE_NORMAL = 0;
	private static final int STATE_SELECT_RECT = 1;
	
	private int state = STATE_NORMAL;
	private SelectionBox selectRectangle;
	
	private Color green = new Color(0.0f, 0.5f, 0.0f);
	private Color red = new Color(0.5f, 0.0f, 0.0f);
	private Color blue = new Color(0.0f, 0.0f, 0.5f);
	
	private PlayerModel model;
	
	private AffineTransform at = new AffineTransform();
	
	public TablePanel(PlayerModel model) {
		super();
		Dbg.logln("TablePanel Constructor");
		changeBackgroundColour("green");
		
		MIL mil = new MIL();
		this.addMouseListener(mil);
		this.addMouseMotionListener(mil);
		setPlayer(model);
		repaint();
	}
	
	public void repaint() {
		Dbg.logln("TablePanel.repaint");
		super.repaint();
	}
	
	public void paintComponent(Graphics g) {
		Dbg.logln("TablePanel.paintComponent");
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D)g;
		g2d.transform(at);
		
		if (model==null) return;
		java.util.List<Card> cards = model.getCards();
		// sort by z
		ZComparator.sort(cards);
		for (Card card: cards) {
			CardView.draw(g2d, card, this);
		}
		
		if (state == STATE_SELECT_RECT) {
			g2d.draw(selectRectangle);
		}
		
	}
	
	public void setPlayer(PlayerModel pm){
		model = pm;
		CardView.setModel(pm);
		model.setTablePanel(this);
		repaint();
	}
	
	public void forceRepaint() {
		Dbg.logln("TablePanel.forceRepaint");
		// ugly fix for the no-repaint bug
		Graphics g = getGraphics();
		if (g!=null) {
			paintComponent(g);
		} else {
			Dbg.logln("null graphics wtf");
		}
	}
	
	public class MIL extends MouseInputAdapter {
		
		public void mousePressed(MouseEvent e) {
			translateMouse(e);
	
			Card selectedCard = null;
			int z = -1;
			Point p = e.getPoint(); //point of click
			
			for(Card card: model.getCards()){
				if(card.getRectangle().contains(p)){//intersects with point
					if(card.getZ() > z){//check if highest z
						z = card.getZ();//set c and z
						selectedCard = card;
					}
				}
			}
			
			state = STATE_NORMAL;
			
			//start selection rectangle
			if (selectedCard == null) {
				model.deselectAllCards();
				state = STATE_SELECT_RECT;
				selectRectangle = new SelectionBox();
				selectRectangle.setStart(e.getX(), e.getY());
				selectRectangle.setEnd(e.getX(), e.getY());
			} else {
				if(!model.isSelectedCard(selectedCard)) {
					model.deselectAllCards();
					model.selectSingleCard(selectedCard);
				} 
				model.dragStart(e.getPoint());
			}
						
		}
		
		public void mouseDragged(MouseEvent e) {
			translateMouse(e);
			
			switch (state) {
			
			case STATE_NORMAL:
				model.dragContinue(e.getPoint());
				break;
				
			//update selection rectangle
			case STATE_SELECT_RECT:
				selectRectangle.setEnd(e.getX(), e.getY());			 	
				repaint();
				break;
			}
		}
		
		public void mouseReleased(MouseEvent e) {
			translateMouse(e);
			
			switch (state) {
			
			case STATE_NORMAL:
				model.dragEnd(e.getPoint());
				break;
				
			case STATE_SELECT_RECT:
			
				for(Card card: model.getCards()){
					
					if(card.getRectangle().intersects(selectRectangle)) {
						model.selectCard(card);
					}
				}				
				
				state = STATE_NORMAL;
				repaint();
				break;
			}			
		}
		
		public void translateMouse(MouseEvent e) {
			e.translatePoint((int)(-e.getX() + e.getX() / at.getScaleX()), (int)(-e.getY() + e.getY() / at.getScaleY()));
		}
	}
	
	public void changeBackgroundColour(String colour) {
		if(colour.equals("green")) {
			this.setBackground(green);
		} else if(colour.equals("red")) {
			this.setBackground(red);
		} else if(colour.equals("blue")) {
			this.setBackground(blue);
		}
	}
	
	
	/**
	 * @param zoom the at to set
	 */
	public void zoom(int zoom) {
		
		double zin = 0.95;
		double zout = 1./zin;
		
		if (zoom>0) {
			at.scale(zin,zin);
		}
		if (zoom<0) {
			at.scale(zout,zout);
		}
	}	
	
}



